package com.yami.shop.common.util.hnaPay;

import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.Objects;

/**
 * 签名验签
 */
public class RSAAlgorithms {

    /**
     * @param publicKey 公钥HEX字符串
     * @return 返回公钥
     */
    public static PublicKey getPublicKey(String publicKey, String algorithm) {
        PublicKey pubKey = null;
        try {
            byte[] encodedKey = HexStringByte.hexToByte(publicKey.getBytes());
            KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
            pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
        } catch (InvalidKeySpecException e) {
            System.out.println("公钥无效!");
        } catch (NoSuchAlgorithmException e) {
            System.out.println("算法类型无效!");
        }
        return pubKey;
    }

    /**
     * @param priKey 私钥
     * @param data   要签名的数据
     * @return 签名消息
     */
    public static byte[] sign(PrivateKey priKey, String data, String signAlgorithm) {
        try {
            Signature signet = Signature.getInstance(signAlgorithm);
            signet.initSign(priKey);
            signet.update(data.getBytes(StandardCharsets.UTF_8));
            return signet.sign();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return null;
    }

    /**
     * 验证签名
     *
     * @param publicKey 公钥HEX字符串
     * @param merData   签名数据
     * @param signMsg   签名消息
     * @return 返回验证结果 true 成功 false 失败
     */
    public static Boolean verify(String publicKey, String merData, String signMsg, String signAlgorithm, String algorithm) {

        boolean bVerify = false;
        Signature signet = null;
        try {
            signet = Signature.getInstance(signAlgorithm);
        } catch (NoSuchAlgorithmException e) {
            System.out.println("算法类型不能为空!");
        }

        PublicKey pubKey = getPublicKey(publicKey, algorithm);

        try {
            Objects.requireNonNull(signet).initVerify(pubKey);
        } catch (InvalidKeyException e) {
            System.out.println("公钥无效!");
        }
        try {
            Objects.requireNonNull(signet).update(merData.getBytes(StandardCharsets.UTF_8));
        } catch (SignatureException e) {
            System.out.println("验签时符号异常!");
        }

        try {
            bVerify = Objects.requireNonNull(signet).verify(HexStringByte.hex2byte(signMsg));
        } catch (SignatureException e) {
            System.out.println("验签异常!");
        }
        return bVerify;
    }

}
